home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / docs / ippon / ver / 014 / enemy.c next >
C/C++ Source or Header  |  2000-07-07  |  3KB  |  147 lines

  1. /* enemy.c */
  2.  
  3. #include <stdio.h>
  4. #include <xsp2lib.h>
  5.  
  6. #include "main.h"
  7. #include "player.h"
  8. #include "shot.h"
  9. #include "enemy.h"
  10.  
  11. #define ENEMY_MAX    32    /* 敵最大数 */
  12.  
  13. static ENEMY enemy[ENEMY_MAX];    /* ワーク */
  14. static ENEMY *enemy_top,    /* 使用中のワークのリスト */
  15.  *enemy_null_top,        /* 空のワークのリスト */
  16.  *enemy_end;            /* 使用中ワークのリストの末尾 */
  17.  
  18.  
  19.  
  20. /* 初期化関数へのポインタの配列 */
  21. typedef void (*enemy_alloc) (ENEMY *);
  22. enemy_alloc EnemyAllocFunc[] =
  23. {
  24.     EnemyAllocZakoA,
  25.     EnemyAllocZakoB,
  26. };
  27.  
  28.  
  29.  
  30. /* ゲーム開始時に呼ばれる */
  31. void EnemyInit (void)
  32. {
  33.     int i;
  34.  
  35.     /* リストをつなげる */
  36.     enemy_top = NULL;
  37.     enemy_end = NULL;
  38.     enemy_null_top = enemy;
  39.     for (i = 0; i < ENEMY_MAX; i++)
  40.         enemy[i].next = &enemy[i + 1];
  41.  
  42.     enemy[ENEMY_MAX - 1].next = NULL;
  43. }
  44.  
  45.  
  46.  
  47. /* 敵出現時に呼ばれる */
  48. ENEMY *EnemyAlloc (short type, signed short x, signed short y)
  49. {
  50.     ENEMY *p;
  51.  
  52.     if (enemy_null_top == NULL)
  53.         return (NULL);    /* 空きのワークがない(キャラクターオーバー) */
  54.  
  55.     /* リストの末尾に新しいノードを追加(他とは違うので注意) */
  56.     p = enemy_null_top;
  57.     enemy_null_top = p->next;
  58.     if (enemy_top == NULL)
  59.         enemy_top = p;
  60.     else
  61.         enemy_end->next = p;
  62.     p->next = NULL;
  63.     enemy_end = p;
  64.  
  65.     p->type = type;
  66.     p->lx = x << 16;
  67.     p->ly = y << 16;
  68.  
  69.     /* 関数へのポインタを使って分岐 */
  70.     /* type が 0 なら EnemyAllocA() が、1 なら EnemyAllocB() が実行される */
  71.     EnemyAllocFunc[p->type] (p);
  72.  
  73.     return (p);
  74. }
  75.  
  76.  
  77.  
  78. /* 垂直同期ごとに呼ばれる */
  79. void EnemyMove (void)
  80. {
  81.     ENEMY *p, *q;
  82.     signed short pl_x = player->x, pl_y = player->y;
  83.  
  84.     p = enemy_top;        /* 現在注目しているワーク */
  85.     q = NULL;        /* 1つ前のワーク(ワーク削除時に必要) */
  86.     while (p != NULL) {
  87.         /* 敵キャラの移動ルーチン */
  88.  
  89.         /* 関数へのポインタを使って分岐 */
  90.         /* (FuncEnemy/ 以下の FuncMoveXXX() を呼んでいる) */
  91.         if ((p->func_enemy_move) (p)) {        /* 返り値が非0なら消去 */
  92.             (p->func_enemy_free) (p);    /* 消去関数を呼ぶ */
  93.             if (q == NULL) {    /* リストの一番最初を削除 */
  94.                 enemy_top = p->next;
  95.                 p->next = enemy_null_top;
  96.                 enemy_null_top = p;
  97.                 q = NULL;
  98.                 p = enemy_top;
  99.             } else {
  100.                 if (p == enemy_end) {    /* リストの一番最後を削除 */
  101.                     q->next = NULL;
  102.                     enemy_end = q;
  103.                     p->next = enemy_null_top;
  104.                     enemy_null_top = p;
  105.                     p = q->next;
  106.                 } else {
  107.                     q->next = p->next;
  108.                     p->next = enemy_null_top;
  109.                     enemy_null_top = p;
  110.                     p = q->next;
  111.                 }
  112.             }
  113.         } else {
  114.             /* 敵キャラを消去しない場合 */
  115.             SHOT *p2 = shot_top;    /* 現在注目しているショットのワーク */
  116.             signed short t;
  117.  
  118.             /* プレイヤーとの当たり判定 */
  119.             if (((t = p->x + p->hit_sx) > pl_x)
  120.                 && ((t -= (short) (p->hit_sx << 1)) < pl_x)
  121.                 && ((t = p->y + p->hit_sy) > pl_y)
  122.                 && ((t -= (short) (p->hit_sy << 1)) < pl_y)) {
  123.                 /* 当たった */
  124.                 if (player->status == PLAYER_STATUS_ALIVE)
  125.                     player->status = PLAYER_STATUS_DEAD;
  126.             }
  127.             /* ショットとの当たり判定 */
  128.             while (p2 != NULL) {
  129.                 signed short p2_w;
  130.                 short hit_w;
  131.                 if (((t = p->x + (hit_w = p->hit_sx)) >= (p2_w = *((short *) (&p2->lx))))
  132.                     && ((t -= (short) (hit_w << 1)) <= p2_w)
  133.                     && ((t = p->y + (hit_w = p->hit_sy)) >= (p2_w = *((short *) (&p2->ly))))
  134.                     && ((t -= (short) (hit_w << 1)) <= p2_w)
  135.                     && (p2->damage == 0)) {
  136.                     /* ショットが当たった */
  137.                     p->damage++;    /* 敵キャラにダメージを与える */
  138.                     p2->damage = !0;    /* 自機ショットに当たった事を知らせる */
  139.                 }
  140.                 p2 = p2->next;
  141.             }
  142.             q = p;
  143.             p = p->next;
  144.         }
  145.     }
  146. }
  147.